#include "Export/export.h"
#include "napi/native_api.h"
#include "mlog.h"
#include <asm-generic/stat.h>
#include <ace/xcomponent/native_interface_xcomponent.h>
#include <bits/alltypes.h>
#include <rawfile/raw_file_manager.h>
#include "napi.h"
#include "thread/thread.h"
static napi_threadsafe_function g_threadsafe_func_handle = nullptr;//threadsafe 函数引用
static napi_ref g_func_ref=nullptr;//函数引用 
static glesmain glesmain_;

glesmain* getGlesmain()
{
    return &glesmain_;
}
 static void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) {
    glesmain_.OnSurfaceCreateCB(component, window);
}
static void OnSurfaceChangedCB(OH_NativeXComponent *component, void *window) { MLOG("OnSurfaceChangedCB"); }
static void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window) { MLOG("OnSurfaceDestroyedCB"); }
static void DispatchTouchEventCB(OH_NativeXComponent *component, void *window) {
    auto t = getThreadID();
    MLOGFormat("DispatchTouchEventCB thread=%{public}lld", t);
    OH_NativeXComponent_TouchEvent event;
    OH_NativeXComponent_GetTouchEvent(component, window,&event);

    auto data = GetCallBackData(Touch);
    data.reg_data[0] = event.id; // 这个寄存器数据，ts端拿到的是同一块内存
    data.reg_data[1] = (uint32_t)event.x;
    data.reg_data[2] = (uint32_t)event.y;
    data.reg_data[3] = event.type; // 0 down 1 up
    DispatchEvent(Touch, Thread_Block);//同一个线程，可以用Direct
}

static void DispatchMouseEventCB(OH_NativeXComponent *component, void *window) { MLOG("DispatchMouseEventCB"); }
static void DispatchHoverEventCB(OH_NativeXComponent *component, bool isHover) { MLOG("DispatchHoverEventCB"); }

// 回调对象传的指针，不能销毁
static OH_NativeXComponent_Callback renderCallback_;
static OH_NativeXComponent_MouseEvent_Callback mouseCallback_;
static void xcomponent_init(napi_env env, napi_value exports) {

        // 初始化XComponent
        // OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "===ATGame===Init", "初始化 XComponent");
    MLOG("xcomponent_init.初始化 XComponent");
    napi_value exportInstance = nullptr;
    if (napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
        MLOG("Export: napi_get_named_property fail");
        return;
    }
    MLOG("xcomponent_init.得到 XComponent Instance");

    OH_NativeXComponent *nativeXComponent = nullptr;
    if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginManager", "Export: napi_unwrap fail");
        return;
    }
    MLOG("xcomponent_init.得到 XComponent 指针");

    char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
    uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
    if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginManager",
                     "Export: OH_NativeXComponent_GetXComponentId fail");
        return;
    }


    MLOGFormat("component_init.得到 XComponent id =%{public}s", idStr);
    // 莫名奇妙的crash，问题出在哪里了？？
    // Log("xcomponent_init.得到 XComponent id %s", idStr);
    // 设置回调
    MLOGFormat("xcomponent_init thread=%{public}16x", getThreadID());


    renderCallback_.OnSurfaceCreated = OnSurfaceCreatedCB;
    renderCallback_.OnSurfaceChanged = OnSurfaceChangedCB;
    renderCallback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
    renderCallback_.DispatchTouchEvent = DispatchTouchEventCB;
    OH_NativeXComponent_RegisterCallback(nativeXComponent, &renderCallback_);

    mouseCallback_.DispatchMouseEvent = DispatchMouseEventCB;
    mouseCallback_.DispatchHoverEvent = DispatchHoverEventCB;
    OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent, &mouseCallback_);
}


EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {

    xcomponent_init(env, exports);
    
//    napi_property_descriptor desc[] = {
//        //{"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr}
//        {"Game_Init", nullptr, napi_Init, nullptr, nullptr, nullptr, napi_default, nullptr},
//        {"Game_SetCallBack", nullptr, napi_Game_SetCallBack, nullptr, nullptr, nullptr, napi_default, nullptr},
//        {"Game_GetReg_Entity", nullptr, napi_Game_GetReg_Entity, nullptr, nullptr, nullptr, napi_default, nullptr},
//        {"Game_CreateEntity", nullptr, napi_Game_CreateEntity, nullptr, nullptr, nullptr, napi_default, nullptr},
//    };
//    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);

    ExportNAPIFunction(env, exports);

    return exports;
}
EXTERN_C_END

static napi_module mainModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "arktsgame",
    .nm_priv = ((void *)0),
    .reserved = {0},
};

extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&mainModule); }
